www.gusucode.com > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序 > VC++ Flash(SWF)文件创建生成Lib库源码+demo-源码程序/code/SWFLIB_Library/SWFShape.cpp

    // SWFShape.cpp: implementation of the CSWFShape class.
//
//////////////////////////////////////////////////////////////////////

#include "SWFShape.h"


CSWFShape::CSWFShape(USHORT nID, RECT_F rectangle, USHORT depth)
{
	// Init DefineShape struct
	m_ObjectType = SWF_OBJECT_TYPE_SHAPE;
	m_ID = nID;
	m_Depth = depth;
	m_Shape.ShapeID = nID;
	m_Shape.Header.TagCodeAndLength = (32 << 6) | 0x003F;
	m_Shape.Header.Length = 0;

	// Init shape bound rectangle
	m_ShapeRectangle.SetRectangle(rectangle);

	// Init shape properties
	m_Shape.Shapes.NumberOfFillAndLineIndexBits = 0;
	m_Shape.Shapes.LineStyles.LineStyleCount = 0xFF;
	m_Shape.Shapes.LineStyles.LineStyleCountExtended = 0;
	m_Shape.Shapes.LineStyles.LineStyles = NULL;
	m_Shape.Shapes.FillStyles.FillStyleCount = 0xFF;
	m_Shape.Shapes.FillStyles.FillStyleCountExtended = 0;
	m_Shape.Shapes.FillStyles.FillStyles = NULL;
	m_Shape.Shapes.ShapeRecords = NULL;
	memset(&m_TransformationMatrix, 0, sizeof(MATRIX_F));

	// Init shape counter
	m_NumberShapes = 0;

	// Init shape stream properties
	m_SWFStream = NULL;
	m_SWFStreamLength = 0;
}

CSWFShape::~CSWFShape()
{
	// Free LineStyleArray
	if (m_Shape.Shapes.LineStyles.LineStyles != NULL)
	{
		free(m_Shape.Shapes.LineStyles.LineStyles);
		m_Shape.Shapes.LineStyles.LineStyles = NULL;
	}

	// Free FillStyleArray
	if (m_Shape.Shapes.FillStyles.FillStyles != NULL)
	{
		// Free GradientRecordsArray
		for (int i=0; i<m_Shape.Shapes.FillStyles.FillStyleCountExtended; i++)
		{
			if ((m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || 
				(m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_RADIALGRADIENT))
			{
				delete m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.GradientRecords;
				m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.GradientRecords = NULL;
			}
		}
		free(m_Shape.Shapes.FillStyles.FillStyles);
		m_Shape.Shapes.FillStyles.FillStyles = NULL;
	}

	// Free ShapeRecordsArray
	if (m_Shape.Shapes.ShapeRecords != NULL)
	{
		free(m_Shape.Shapes.ShapeRecords);
		m_Shape.Shapes.ShapeRecords = NULL;
	}

	// Free shape stream
	if (m_SWFStream != NULL)
	{
		free(m_SWFStream);
		m_SWFStream = NULL;
	}
}

void CSWFShape::AddLineStyle(int lineWidth, SWF_RGBA lineColor)
{
	// Define new LineStyle entry
	SWF_LINESTYLE lineStyleEntry;
	memset(&lineStyleEntry, 0, sizeof(SWF_LINESTYLE));
	lineStyleEntry.Width = (USHORT)(lineWidth*20);
	memcpy(&lineStyleEntry.Color, &lineColor, sizeof(SWF_RGBA));

	// Add new LineStyle entry to the LineStyleArray
	m_Shape.Shapes.LineStyles.LineStyleCountExtended++;
	if (m_Shape.Shapes.LineStyles.LineStyles == NULL)
		m_Shape.Shapes.LineStyles.LineStyles = (SWF_LINESTYLE*)malloc(sizeof(SWF_LINESTYLE));
	else
		m_Shape.Shapes.LineStyles.LineStyles = (SWF_LINESTYLE*)realloc(m_Shape.Shapes.LineStyles.LineStyles, m_Shape.Shapes.LineStyles.LineStyleCountExtended*sizeof(SWF_LINESTYLE));
	memcpy(&m_Shape.Shapes.LineStyles.LineStyles[m_Shape.Shapes.LineStyles.LineStyleCountExtended-1], &lineStyleEntry, sizeof(SWF_LINESTYLE));
}

void CSWFShape::AddSolidFillStyle(SWF_RGBA fillColor)
{
	// Define new FillStyle entry
	SWF_FILLSTYLE fillStyleEntry;
	memset(&fillStyleEntry, 0, sizeof(SWF_FILLSTYLE));
	fillStyleEntry.FillStyleType = SWF_FILLSTYLETYPE_SOLID;
	memcpy(&fillStyleEntry.Color, &fillColor, sizeof(SWF_RGBA));

	// Add new FillStyle entry to the FillStyleArray
	m_Shape.Shapes.FillStyles.FillStyleCountExtended++;
	if (m_Shape.Shapes.FillStyles.FillStyles == NULL)
		m_Shape.Shapes.FillStyles.FillStyles = (SWF_FILLSTYLE*)malloc(sizeof(SWF_FILLSTYLE));
	else
		m_Shape.Shapes.FillStyles.FillStyles = (SWF_FILLSTYLE*)realloc(m_Shape.Shapes.FillStyles.FillStyles, m_Shape.Shapes.FillStyles.FillStyleCountExtended*sizeof(SWF_FILLSTYLE));
	memcpy(&m_Shape.Shapes.FillStyles.FillStyles[m_Shape.Shapes.FillStyles.FillStyleCountExtended-1], &fillStyleEntry, sizeof(SWF_FILLSTYLE));
}

void CSWFShape::AddGradientFillStyle(UCHAR gradientFillType, RECT_F gradientRect, SWF_GRADIENTRECORD* gradientRecords, int numRecords)
{
	if ((numRecords > 0) && ((gradientFillType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || (gradientFillType == SWF_FILLSTYLETYPE_RADIALGRADIENT)))
	{
		// Define gradient matrix
		MATRIX_F gradientMatrix;
		memset(&gradientMatrix, 0, sizeof(MATRIX_F));
		gradientMatrix.scaleX = ((gradientRect.right-gradientRect.left)*20) / 32768;
		gradientMatrix.scaleY = ((gradientRect.bottom-gradientRect.top)*20) / 32768;
		gradientMatrix.translateX = (gradientRect.left+gradientRect.right) / 2;
		gradientMatrix.translateY = (gradientRect.top+gradientRect.bottom) / 2;

		// Define new FillStyle entry
		SWF_FILLSTYLE fillStyleEntry;
		memset(&fillStyleEntry, 0, sizeof(SWF_FILLSTYLE));
		fillStyleEntry.FillStyleType = gradientFillType;
		fillStyleEntry.GradientMatrix = gradientMatrix;
		fillStyleEntry.Gradient.NumGradients = numRecords;
		fillStyleEntry.Gradient.GradientRecords = new SWF_GRADIENTRECORD[numRecords];
		memcpy(fillStyleEntry.Gradient.GradientRecords, gradientRecords, numRecords*sizeof(SWF_GRADIENTRECORD));

		// Add new FillStyle entry to the FillStyleArray
		m_Shape.Shapes.FillStyles.FillStyleCountExtended++;
		if (m_Shape.Shapes.FillStyles.FillStyles == NULL)
			m_Shape.Shapes.FillStyles.FillStyles = (SWF_FILLSTYLE*)malloc(sizeof(SWF_FILLSTYLE));
		else
			m_Shape.Shapes.FillStyles.FillStyles = (SWF_FILLSTYLE*)realloc(m_Shape.Shapes.FillStyles.FillStyles, m_Shape.Shapes.FillStyles.FillStyleCountExtended*sizeof(SWF_FILLSTYLE));
		memcpy(&m_Shape.Shapes.FillStyles.FillStyles[m_Shape.Shapes.FillStyles.FillStyleCountExtended-1], &fillStyleEntry, sizeof(SWF_FILLSTYLE));
	}
}

void CSWFShape::AddBitmapFillStyle(USHORT bitmapID, UCHAR bitmapFillType, RECT_F bitmapRect, RECT_F clipRect)
{
	if ((bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_0) || (bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_1) ||
		(bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_2) || (bitmapFillType == SWF_FILLSTYLETYPE_BITMAP_3))
	{
		// Define bitmap matrix
		MATRIX_F bitmapMatrix;
		memset(&bitmapMatrix, 0, sizeof(MATRIX_F));
		bitmapMatrix.scaleX = ((clipRect.right-clipRect.left)/(bitmapRect.right-bitmapRect.left)) * 20;
		bitmapMatrix.scaleY = ((clipRect.bottom-clipRect.top)/(bitmapRect.bottom-bitmapRect.top)) * 20;
		bitmapMatrix.translateX = clipRect.left;
		bitmapMatrix.translateY = clipRect.top;

		// Define new FillStyle entry
		SWF_FILLSTYLE fillStyleEntry;
		memset(&fillStyleEntry, 0, sizeof(SWF_FILLSTYLE));
		fillStyleEntry.FillStyleType = bitmapFillType;
		fillStyleEntry.BitmapID = bitmapID;
		fillStyleEntry.BitmapMatrix = bitmapMatrix;

		// Add new FillStyle entry to the FillStyleArray
		m_Shape.Shapes.FillStyles.FillStyleCountExtended++;
		if (m_Shape.Shapes.FillStyles.FillStyles == NULL)
			m_Shape.Shapes.FillStyles.FillStyles = (SWF_FILLSTYLE*)malloc(sizeof(SWF_FILLSTYLE));
		else
			m_Shape.Shapes.FillStyles.FillStyles = (SWF_FILLSTYLE*)realloc(m_Shape.Shapes.FillStyles.FillStyles, m_Shape.Shapes.FillStyles.FillStyleCountExtended*sizeof(SWF_FILLSTYLE));
		memcpy(&m_Shape.Shapes.FillStyles.FillStyles[m_Shape.Shapes.FillStyles.FillStyleCountExtended-1], &fillStyleEntry, sizeof(SWF_FILLSTYLE));
	}
}

void CSWFShape::ChangeStyle(int lineStyleIndex, int fillStyleIndex0, int fillStyleIndex1, POINT_F* newPosition)
{
	// Define new StyleChange entry
	SWF_SHAPERECORD styleChangeEntry;
	memset(&styleChangeEntry, 0, sizeof(SWF_SHAPERECORD));

	// StateLineStyle bit
	styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x08;
	styleChangeEntry.SWF_STYLECHANGERECORD.LineStyle = (SHORT)lineStyleIndex;

	// StateFillStyle1 bit
	styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x04;
	styleChangeEntry.SWF_STYLECHANGERECORD.FillStyle1 = (SHORT)fillStyleIndex1;

	// StateFillStyle0 bit
	styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x02;
	styleChangeEntry.SWF_STYLECHANGERECORD.FillStyle0 = (SHORT)fillStyleIndex0;

	// StateMoveTo bit
	if (newPosition != NULL)
	{
		styleChangeEntry.SWF_STYLECHANGERECORD.ShapeFlags |= 0x01;
		styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaX = (LONG)(newPosition->x * 20);
		styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaY = (LONG)(newPosition->y * 20);

		// Calculate MoveBits
		int maxValue = max(abs(styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaX), abs(styleChangeEntry.SWF_STYLECHANGERECORD.MoveDeltaY));
		BYTE numMoveBits = 0;
		while (pow(2,numMoveBits) < maxValue)
			numMoveBits++;
		numMoveBits++;
		styleChangeEntry.SWF_STYLECHANGERECORD.MoveBits = numMoveBits;
	}

	// Add new StyleChange to the ShapeRecordsArray
	m_NumberShapes++;
	if (m_Shape.Shapes.ShapeRecords == NULL)
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD));
	else
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_Shape.Shapes.ShapeRecords, m_NumberShapes*sizeof(SWF_SHAPERECORD));
	memcpy(&m_Shape.Shapes.ShapeRecords[m_NumberShapes-1], &styleChangeEntry, sizeof(SWF_SHAPERECORD));
}

void CSWFShape::AddLineSegment(POINT_F offsetPoint)
{
	// Define new StraightEdge entry
	SWF_SHAPERECORD straightEdgeEntry;
	memset(&straightEdgeEntry, 0, sizeof(SWF_SHAPERECORD));
	straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags = 0x30;
	straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaX = (int)(offsetPoint.x * 20);
	straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaY = (int)(offsetPoint.y * 20);

	// Calculate NumBits
	int maxValue = max(abs(straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaX), abs(straightEdgeEntry.SWF_STRAIGHTEDGERECORD.DeltaY));
	BYTE numBits = 0;
	while (pow(2,numBits) < maxValue)
		numBits++;
	numBits++;
	straightEdgeEntry.SWF_STRAIGHTEDGERECORD.NumBits = numBits;
	straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags |= ((straightEdgeEntry.SWF_STRAIGHTEDGERECORD.NumBits-2) & 0x0F);
	straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags = (straightEdgeEntry.SWF_STRAIGHTEDGERECORD.ShapeFlags << 1) | 0x01;

	// Add new StraightEdge to the ShapeRecordsArray
	m_NumberShapes++;
	if (m_Shape.Shapes.ShapeRecords == NULL)
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD));
	else
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_Shape.Shapes.ShapeRecords, m_NumberShapes*sizeof(SWF_SHAPERECORD));
	memcpy(&m_Shape.Shapes.ShapeRecords[m_NumberShapes-1], &straightEdgeEntry, sizeof(SWF_SHAPERECORD));
}

void CSWFShape::AddLineSegment(float xOffset, float yOffset)
{
	// Add new StraightEdge to the ShapeRecordsArray
	POINT_F newPosition = {xOffset, yOffset};
	AddLineSegment(newPosition);
}

void CSWFShape::AddCurveSegment(POINT_F controlPoint, POINT_F anchorPoint)
{
	// Define new CurvedEdge entry
	SWF_SHAPERECORD curvedEdgeEntry;
	memset(&curvedEdgeEntry, 0, sizeof(SWF_SHAPERECORD));
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.ShapeFlags = 0x20;
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaX = (int)(controlPoint.x * 20);
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaY = (int)(controlPoint.y * 20);
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaX = (int)(anchorPoint.x * 20);
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaY = (int)(anchorPoint.y * 20);

	// Calculate NumBits
	int maxControlValue = max(abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaX), abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.ControlDeltaY));
	int maxDeltaValue = max(abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaX), abs(curvedEdgeEntry.SWF_CURVEDEDGERECORD.AnchorDeltaY));
	int maxValue = max(maxControlValue, maxDeltaValue);
	BYTE numBits = 0;
	while (pow(2,numBits) < maxValue)
		numBits++;
	numBits++;
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.NumBits = numBits;
	curvedEdgeEntry.SWF_CURVEDEDGERECORD.ShapeFlags |= ((curvedEdgeEntry.SWF_CURVEDEDGERECORD.NumBits-2) & 0x0F);

	// Add new CurvedEdge to the ShapeRecordsArray
	m_NumberShapes++;
	if (m_Shape.Shapes.ShapeRecords == NULL)
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD));
	else
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_Shape.Shapes.ShapeRecords, m_NumberShapes*sizeof(SWF_SHAPERECORD));
	memcpy(&m_Shape.Shapes.ShapeRecords[m_NumberShapes-1], &curvedEdgeEntry, sizeof(SWF_SHAPERECORD));
}

void CSWFShape::AddCurveSegment(float controlPointX, float controlPointY, float anchorPointX, float anchorPointY)
{
	POINT_F controlPoint = {controlPointX, controlPointY};
	POINT_F anchorPoint = {anchorPointX, anchorPointY};
	AddCurveSegment(controlPoint, anchorPoint);
}

UCHAR* CSWFShape::BuildSWFStream()
{
	int newLength;
	BYTE numFillIndexBits=0, numLineIndexBits=0;
	UCHAR* pShapeRecordBuffer = NULL;
	int recordStreamLength = 0;

	// Free shape stream
	if (m_SWFStream != NULL)
	{
		free(m_SWFStream);
		m_SWFStream = NULL;
	}

	// Add new EndShapeRecord to the ShapeRecordArray
	SWF_SHAPERECORD endShapeRecord;
	memset(&endShapeRecord, 0, sizeof(SWF_SHAPERECORD));
	m_NumberShapes++;
	if (m_Shape.Shapes.ShapeRecords == NULL)
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)malloc(sizeof(SWF_SHAPERECORD));
	else
		m_Shape.Shapes.ShapeRecords = (SWF_SHAPERECORD*)realloc(m_Shape.Shapes.ShapeRecords, m_NumberShapes*sizeof(SWF_SHAPERECORD));
	memcpy(&m_Shape.Shapes.ShapeRecords[m_NumberShapes-1], &endShapeRecord, sizeof(SWF_SHAPERECORD));

	// Build shape bounds rectangle .SWF stream
	UCHAR* pBuffer = m_ShapeRectangle.BuildSWFStream();

	// Calculate total shape tag length
	m_Shape.Header.Length += m_ShapeRectangle.GetSWFStreamLength();			// Length of ShapeBounds rectangle
	m_Shape.Header.Length += sizeof(USHORT);								// Length of ShapeID
	m_Shape.Header.Length += sizeof(UCHAR);									// Length of NumLineAndFillBits field
	// Length of FillStyleArray
	if (m_Shape.Shapes.FillStyles.FillStyleCountExtended != 0)
	{
		// Calculate NumFillIndexBits
		while (pow(2,numFillIndexBits) < (m_Shape.Shapes.FillStyles.FillStyleCountExtended+1))
			numFillIndexBits++;
		int fillStyleArraySize = sizeof(UCHAR);
		if (m_Shape.Shapes.FillStyles.FillStyleCountExtended > 255)
			fillStyleArraySize += sizeof(USHORT);
		for (int i=0; i<m_Shape.Shapes.FillStyles.FillStyleCountExtended; i++)
		{
			if (m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_SOLID)
				fillStyleArraySize += (sizeof(UCHAR) + sizeof(SWF_RGBA));
			else if ((m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || 
				(m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_RADIALGRADIENT))
			{
				CSWFMatrix gradientMatrix;
				gradientMatrix.SetMatrix(m_Shape.Shapes.FillStyles.FillStyles[i].GradientMatrix);
				gradientMatrix.BuildSWFStream();
				fillStyleArraySize += 2*sizeof(UCHAR);
				fillStyleArraySize += gradientMatrix.GetSWFStreamLength();
				fillStyleArraySize += m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.NumGradients*sizeof(SWF_GRADIENTRECORD);
			}
			else if ((m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_0) || (m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_1) || 
				(m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_2) || (m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_3))
			{
				CSWFMatrix bitmapMatrix;
				bitmapMatrix.SetMatrix(m_Shape.Shapes.FillStyles.FillStyles[i].BitmapMatrix);
				bitmapMatrix.BuildSWFStream();
				fillStyleArraySize += (sizeof(UCHAR) + sizeof(USHORT));
				fillStyleArraySize += bitmapMatrix.GetSWFStreamLength();
			}
		}
		m_Shape.Header.Length += fillStyleArraySize;
	}
	else
		m_Shape.Header.Length += sizeof(UCHAR);

	// Length of LineStyleArray
	if (m_Shape.Shapes.LineStyles.LineStyleCountExtended != 0)
	{
		// Calculate NumLineIndexBits
		while (pow(2,numLineIndexBits) < (m_Shape.Shapes.LineStyles.LineStyleCountExtended+1))
			numLineIndexBits++;
		int lineStyleArraySize = sizeof(UCHAR) + m_Shape.Shapes.LineStyles.LineStyleCountExtended*sizeof(SWF_LINESTYLE);
		if (m_Shape.Shapes.LineStyles.LineStyleCountExtended > 255)
			lineStyleArraySize += sizeof(USHORT);
		m_Shape.Header.Length += lineStyleArraySize;
	}
	else
		m_Shape.Header.Length += sizeof(UCHAR);
	// Length of ShapeRecordArray
	if (m_NumberShapes != 0)
	{
		// Build RecordArray .SWF stream
		pShapeRecordBuffer = BuildRecordArraySWFStream(numLineIndexBits, numFillIndexBits, recordStreamLength);
		m_Shape.Header.Length += recordStreamLength;
	}
	else
		m_Shape.Header.Length += sizeof(UCHAR);

	// Write RecordHeader tag to .SWF stream
	newLength = m_SWFStreamLength + sizeof(SWF_RECORDHEADER_LONG);
	if (m_SWFStreamLength == 0)
		m_SWFStream = (BYTE*)malloc(newLength);
	else
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
	memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Header, sizeof(SWF_RECORDHEADER_LONG));
	m_SWFStreamLength = newLength;

	// Write ShapeID to .SWF stream
	newLength = m_SWFStreamLength + sizeof(USHORT);
	if (m_SWFStreamLength == 0)
		m_SWFStream = (BYTE*)malloc(newLength);
	else
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
	memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.ShapeID, sizeof(USHORT));
	m_SWFStreamLength = newLength;

	// Write ShapeBounds tag to .SWF stream
	newLength = m_SWFStreamLength + m_ShapeRectangle.GetSWFStreamLength();
	if (m_SWFStreamLength == 0)
		m_SWFStream = (BYTE*)malloc(newLength);
	else
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
	memcpy(m_SWFStream+m_SWFStreamLength, pBuffer, m_ShapeRectangle.GetSWFStreamLength());
	m_SWFStreamLength = newLength;

	// Write FillStyleArray to .SWF stream
	if (m_Shape.Shapes.FillStyles.FillStyleCountExtended != 0)
	{
		if (m_Shape.Shapes.FillStyles.FillStyleCountExtended < 255)
			m_Shape.Shapes.FillStyles.FillStyleCount = (UCHAR)m_Shape.Shapes.FillStyles.FillStyleCountExtended;

		// Write FillStyleCount to .SWF stream
		newLength = m_SWFStreamLength + sizeof(UCHAR);
		if (m_SWFStreamLength == 0)
			m_SWFStream = (BYTE*)malloc(newLength);
		else
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
		memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyleCount, sizeof(UCHAR));
		m_SWFStreamLength = newLength;

		if (m_Shape.Shapes.FillStyles.FillStyleCountExtended > 255)
		{
			// Write FillStyleCountExtended to .SWF stream
			newLength = m_SWFStreamLength + sizeof(USHORT);
			if (m_SWFStreamLength == 0)
				m_SWFStream = (BYTE*)malloc(newLength);
			else
				m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
			memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyleCountExtended, sizeof(USHORT));
			m_SWFStreamLength = newLength;
		}

		// Write FillStyles to .SWF stream
		for (int i=0; i<m_Shape.Shapes.FillStyles.FillStyleCountExtended; i++)
		{
			// Write FillStyle to .SWF stream
			if (m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_SOLID)
			{
				newLength = m_SWFStreamLength + sizeof(UCHAR) + sizeof(SWF_RGBA);
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType, sizeof(UCHAR));
				memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR), &m_Shape.Shapes.FillStyles.FillStyles[i].Color, sizeof(SWF_RGBA));
				m_SWFStreamLength = newLength;
			}
			else if ((m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_LINEARGRADIENT) || 
				(m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_RADIALGRADIENT))
			{
				newLength = m_SWFStreamLength + sizeof(UCHAR);
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType, sizeof(UCHAR));
				m_SWFStreamLength = newLength;

				CSWFMatrix gradientMatrix;
				gradientMatrix.SetMatrix(m_Shape.Shapes.FillStyles.FillStyles[i].GradientMatrix);
				UCHAR* pGradientMatrixBuffer = gradientMatrix.BuildSWFStream();
				int nGradientMatrixLength = gradientMatrix.GetSWFStreamLength();

				newLength = m_SWFStreamLength + nGradientMatrixLength;
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, pGradientMatrixBuffer, nGradientMatrixLength);
				m_SWFStreamLength = newLength;

				newLength = m_SWFStreamLength + sizeof(UCHAR);
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.NumGradients, sizeof(UCHAR));
				m_SWFStreamLength = newLength;

				for (int j=0; j<m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.NumGradients; j++)
				{
					newLength = m_SWFStreamLength + sizeof(UCHAR) + sizeof(SWF_RGBA);
					if (m_SWFStreamLength == 0)
						m_SWFStream = (BYTE*)malloc(newLength);
					else
						m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
					memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.GradientRecords[j].Ratio, sizeof(UCHAR));
					memcpy(m_SWFStream+m_SWFStreamLength+sizeof(UCHAR), &m_Shape.Shapes.FillStyles.FillStyles[i].Gradient.GradientRecords[j].Color, sizeof(SWF_RGBA));
					m_SWFStreamLength = newLength;
				}
			}
			else if ((m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_0) || (m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_1) || 
				(m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_2) || (m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType == SWF_FILLSTYLETYPE_BITMAP_3))
			{
				newLength = m_SWFStreamLength + sizeof(UCHAR);
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyles[i].FillStyleType, sizeof(UCHAR));
				m_SWFStreamLength = newLength;

				newLength = m_SWFStreamLength + sizeof(USHORT);
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyles[i].BitmapID, sizeof(USHORT));
				m_SWFStreamLength = newLength;

				CSWFMatrix bitmapMatrix;
				bitmapMatrix.SetMatrix(m_Shape.Shapes.FillStyles.FillStyles[i].BitmapMatrix);
				UCHAR* pBitmapMatrixBuffer = bitmapMatrix.BuildSWFStream();
				int nBitmapMatrixLength = bitmapMatrix.GetSWFStreamLength();

				newLength = m_SWFStreamLength + nBitmapMatrixLength;
				if (m_SWFStreamLength == 0)
					m_SWFStream = (BYTE*)malloc(newLength);
				else
					m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
				memcpy(m_SWFStream+m_SWFStreamLength, pBitmapMatrixBuffer, nBitmapMatrixLength);
				m_SWFStreamLength = newLength;
			}
		}
	}
	else
	{
		// Write empty FillStyleArray to .SWF stream
		m_Shape.Shapes.FillStyles.FillStyleCount = 0;
		newLength = m_SWFStreamLength + sizeof(UCHAR);
		if (m_SWFStreamLength == 0)
			m_SWFStream = (BYTE*)malloc(newLength);
		else
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
		memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.FillStyles.FillStyleCount, sizeof(UCHAR));
		m_SWFStreamLength = newLength;
	}

	// Write LineStyleArray to .SWF stream
	if (m_Shape.Shapes.LineStyles.LineStyleCountExtended != 0)
	{
		if (m_Shape.Shapes.LineStyles.LineStyleCountExtended < 255)
			m_Shape.Shapes.LineStyles.LineStyleCount = (UCHAR)m_Shape.Shapes.LineStyles.LineStyleCountExtended;

		// Write LineStyleCount to .SWF stream
		newLength = m_SWFStreamLength + sizeof(UCHAR);
		if (m_SWFStreamLength == 0)
			m_SWFStream = (BYTE*)malloc(newLength);
		else
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
		memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.LineStyles.LineStyleCount, sizeof(UCHAR));
		m_SWFStreamLength = newLength;
		
		if (m_Shape.Shapes.LineStyles.LineStyleCountExtended > 255)
		{
			// Write LineStyleCountExtended to .SWF stream
			newLength = m_SWFStreamLength + sizeof(USHORT);
			if (m_SWFStreamLength == 0)
				m_SWFStream = (BYTE*)malloc(newLength);
			else
				m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
			memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.LineStyles.LineStyleCountExtended, sizeof(USHORT));
			m_SWFStreamLength = newLength;
		}

		// Write LineStyles to .SWF stream
		for (int i=0; i<m_Shape.Shapes.LineStyles.LineStyleCountExtended; i++)
		{
			// Write LineStyle to .SWF stream
			newLength = m_SWFStreamLength + sizeof(SWF_LINESTYLE);
			if (m_SWFStreamLength == 0)
				m_SWFStream = (BYTE*)malloc(newLength);
			else
				m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
			memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.LineStyles.LineStyles[i], sizeof(SWF_LINESTYLE));
			m_SWFStreamLength = newLength;
		}
	}
	else
	{
		// Write empty LineStyleArray to .SWF stream
		m_Shape.Shapes.LineStyles.LineStyleCount = 0;
		newLength = m_SWFStreamLength + sizeof(UCHAR);
		if (m_SWFStreamLength == 0)
			m_SWFStream = (BYTE*)malloc(newLength);
		else
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
		memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.LineStyles.LineStyleCount, sizeof(UCHAR));
		m_SWFStreamLength = newLength;
	}

	// Write NumFillAndLineBits to .SWF stream
	m_Shape.Shapes.NumberOfFillAndLineIndexBits = (numFillIndexBits<<4) | numLineIndexBits;
	newLength = m_SWFStreamLength + sizeof(UCHAR);
	if (m_SWFStreamLength == 0)
		m_SWFStream = (BYTE*)malloc(newLength);
	else
		m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
	memcpy(m_SWFStream+m_SWFStreamLength, &m_Shape.Shapes.NumberOfFillAndLineIndexBits, sizeof(UCHAR));
	m_SWFStreamLength = newLength;

	// Write ShapeRecordArray to .SWF stream
	if (pShapeRecordBuffer != NULL)
	{
		newLength = m_SWFStreamLength + recordStreamLength;
		if (m_SWFStreamLength == 0)
			m_SWFStream = (BYTE*)malloc(newLength);
		else
			m_SWFStream = (BYTE*)realloc(m_SWFStream, newLength);
		memcpy(m_SWFStream+m_SWFStreamLength, pShapeRecordBuffer, recordStreamLength);
		m_SWFStreamLength = newLength;

		// Free memory
		free(pShapeRecordBuffer);
	}

	return m_SWFStream;
}

int CSWFShape::GetSWFStreamLength()
{
	return m_SWFStreamLength;
}

UCHAR* CSWFShape::BuildRecordArraySWFStream(int numLineIndexBits, int numFillIndexBits, int& recordStreamLength)
{
	UCHAR* pShapeRecordBuffer = NULL;
	int numBits=0, bitOffset=0, allocBytes=0;
	recordStreamLength = 0;

	// Write ShapeRecords to .SWF stream
	for (int i=0; i<m_NumberShapes; i++)
	{
		BOOL bEdgeTypeRecord = m_Shape.Shapes.ShapeRecords[i].SWF_ENDSHAPERECORD.ShapeFlags & 0x20;
		BOOL bStraightEdge = m_Shape.Shapes.ShapeRecords[i].SWF_ENDSHAPERECORD.ShapeFlags & 0x10;
		BOOL bStyleChangeRecord = m_Shape.Shapes.ShapeRecords[i].SWF_ENDSHAPERECORD.ShapeFlags & 0x0F;
		
		// Edge type record (StraightEdgeRecord or CurvedEdgeRecord);
		if (bEdgeTypeRecord)
		{
			// StraightEdgeRecord type
			if (bStraightEdge)
			{
				// ShapeFlags bit-field
				numBits += (7 + 2*m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.NumBits);

				// Allocate memory
				if (numBits > (allocBytes*8))
				{
					int oldAllocBytes = allocBytes;
					allocBytes = numBits / 8;
					if ((numBits % 8) != 0)
						allocBytes++;
					if (pShapeRecordBuffer == NULL)
					{
						pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
					}
					else
					{
						UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR));
						memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes);
						pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
						memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes);
						free(pTempBuffer);
					}
				}

				// Write ShapeFlags bit-field
				int currentByte = bitOffset / 8;
				BYTE shapeFlags = m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.ShapeFlags << 1;
				BYTE mask = 0x80;
				for (int j=0; j<7; j++)
				{
					pShapeRecordBuffer[currentByte] |= (((shapeFlags & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					mask = mask >> 1;
				}

				// Write DeltaX bit-field
				ULONG deltaX = m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.DeltaX << (32-m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.NumBits);
				ULONG maskDeltaX = 0x80000000;
				for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.NumBits; j++)
				{
					pShapeRecordBuffer[currentByte] |= LOBYTE(((deltaX & maskDeltaX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					maskDeltaX = maskDeltaX >> 1;
				}

				// Write DeltaY bit-field
				ULONG deltaY = m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.DeltaY << (32-m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.NumBits);
				ULONG maskDeltaY = 0x80000000;
				for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_STRAIGHTEDGERECORD.NumBits; j++)
				{
					pShapeRecordBuffer[currentByte] |= LOBYTE(((deltaY & maskDeltaY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					maskDeltaY = maskDeltaY >> 1;
				}
			}
			// CurvedEdgeRecord type
			else
			{
				// ShapeFlags bit-field
				numBits += (6 + 4*m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits);

				// Allocate memory
				if (numBits > (allocBytes*8))
				{
					int oldAllocBytes = allocBytes;
					allocBytes = numBits / 8;
					if ((numBits % 8) != 0)
						allocBytes++;
					if (pShapeRecordBuffer == NULL)
					{
						pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
					}
					else
					{
						UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR));
						memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes);
						pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
						memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes);
						free(pTempBuffer);
					}
				}

				// Write ShapeFlags bit-field
				int currentByte = bitOffset / 8;
				BYTE shapeFlags = m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.ShapeFlags << 2;
				BYTE mask = 0x80;
				for (int j=0; j<6; j++)
				{
					pShapeRecordBuffer[currentByte] |= (((shapeFlags & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					mask = mask >> 1;
				}

				// Write ControlDeltaX bit-field
				ULONG controlDeltaX = m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.ControlDeltaX << (32-m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits);
				ULONG maskControlDeltaX = 0x80000000;
				for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits; j++)
				{
					pShapeRecordBuffer[currentByte] |= LOBYTE(((controlDeltaX & maskControlDeltaX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					maskControlDeltaX = maskControlDeltaX >> 1;
				}

				// Write ControlDeltaY bit-field
				ULONG controlDeltaY = m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.ControlDeltaY << (32-m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits);
				ULONG maskControlDeltaY = 0x80000000;
				for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits; j++)
				{
					pShapeRecordBuffer[currentByte] |= LOBYTE(((controlDeltaY & maskControlDeltaY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					maskControlDeltaY = maskControlDeltaY >> 1;
				}

				// Write AnchorDeltaX bit-field
				ULONG anchorDeltaX = m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.AnchorDeltaX << (32-m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits);
				ULONG maskAnchorDeltaX = 0x80000000;
				for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits; j++)
				{
					pShapeRecordBuffer[currentByte] |= LOBYTE(((anchorDeltaX & maskAnchorDeltaX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					maskAnchorDeltaX = maskAnchorDeltaX >> 1;
				}

				// Write AnchorDeltaY bit-field
				ULONG anchorDeltaY = m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.AnchorDeltaY << (32-m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits);
				ULONG maskAnchorDeltaY = 0x80000000;
				for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_CURVEDEDGERECORD.NumBits; j++)
				{
					pShapeRecordBuffer[currentByte] |= LOBYTE(((anchorDeltaY & maskAnchorDeltaY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					maskAnchorDeltaY = maskAnchorDeltaY >> 1;
				}
			}
		}
		// Non-edge type record (EndShapeRecord or StyleChangeRecord)
		else
		{
			// StyleChangeRecord type
			if (bStyleChangeRecord)
			{
				// ShapeFlags bit-field
				numBits += 6;

				// StateMoveTo bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x01)
					numBits += (5 + 2*m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveBits);

				// StateFillStyle0 bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x02)
					numBits += numFillIndexBits;

				// StateFillStyle1 bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x04)
					numBits += numFillIndexBits;

				// StateLineStyle bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x08)
					numBits += numLineIndexBits;

				// Allocate memory
				if (numBits > (allocBytes*8))
				{
					int oldAllocBytes = allocBytes;
					allocBytes = numBits / 8;
					if ((numBits % 8) != 0)
						allocBytes++;
					if (pShapeRecordBuffer == NULL)
					{
						pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
					}
					else
					{
						UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR));
						memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes);
						pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
						memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes);
						free(pTempBuffer);
					}
				}

				// Write ShapeFlags bit-field
				int currentByte = bitOffset / 8;
				BYTE shapeFlags = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags << 2;
				BYTE mask = 0x80;
				for (int j=0; j<6; j++)
				{
					pShapeRecordBuffer[currentByte] |= (((shapeFlags & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1));

					bitOffset++;
					if ((bitOffset != 0) && (bitOffset % 8) == 0)
						currentByte++;

					mask = mask >> 1;
				}

				// Write StateMoveTo bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x01)
				{
					int j;
					BYTE shapeMoveBits = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveBits << 3;
					BYTE mask = 0x80;
					for (j=0; j<5; j++)
					{
						pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeMoveBits & mask) >> (7-j)) << ((currentByte+1)*8-bitOffset-1));

						bitOffset++;
						if ((bitOffset != 0) && (bitOffset % 8) == 0)
							currentByte++;

						mask = mask >> 1;
					}

					// Write MoveDeltaX bit-field
					ULONG moveDeltaX = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveDeltaX << (32-m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveBits);
					ULONG maskMoveX = 0x80000000;
					for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveBits; j++)
					{
						pShapeRecordBuffer[currentByte] |= LOBYTE(((moveDeltaX & maskMoveX) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

						bitOffset++;
						if ((bitOffset != 0) && (bitOffset % 8) == 0)
							currentByte++;

						maskMoveX = maskMoveX >> 1;
					}

					// Write MoveDeltaY bit-field
					ULONG moveDeltaY = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveDeltaY << (32-m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveBits);
					ULONG maskMoveY = 0x80000000;
					for (j=0; j<m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.MoveBits; j++)
					{
						pShapeRecordBuffer[currentByte] |= LOBYTE(((moveDeltaY & maskMoveY) >> (31-j)) << ((currentByte+1)*8-bitOffset-1));

						bitOffset++;
						if ((bitOffset != 0) && (bitOffset % 8) == 0)
							currentByte++;

						maskMoveY = maskMoveY >> 1;
					}
				}

				// Write StateFillStyle0 bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x02)
				{
					WORD shapeFillStyleBits = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.FillStyle0 << (16-numFillIndexBits);
					WORD mask = 0x8000;
					for (int j=0; j<numFillIndexBits; j++)
					{
						pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeFillStyleBits & mask) >> (15-j)) << ((currentByte+1)*8-bitOffset-1));

						bitOffset++;
						if ((bitOffset != 0) && (bitOffset % 8) == 0)
							currentByte++;

						mask = mask >> 1;
					}
				}

				// Write StateFillStyle1 bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x04)
				{
					WORD shapeFillStyleBits = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.FillStyle1 << (16-numFillIndexBits);
					WORD mask = 0x8000;
					for (int j=0; j<numFillIndexBits; j++)
					{
						pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeFillStyleBits & mask) >> (15-j)) << ((currentByte+1)*8-bitOffset-1));

						bitOffset++;
						if ((bitOffset != 0) && (bitOffset % 8) == 0)
							currentByte++;

						mask = mask >> 1;
					}
				}

				// Write StateLineStyle bit-field
				if (m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.ShapeFlags & 0x08)
				{
					WORD shapeLineStyleBits = m_Shape.Shapes.ShapeRecords[i].SWF_STYLECHANGERECORD.LineStyle << (16-numLineIndexBits);
					WORD mask = 0x8000;
					for (int j=0; j<numLineIndexBits; j++)
					{
						pShapeRecordBuffer[currentByte] |= LOBYTE(((shapeLineStyleBits & mask) >> (15-j)) << ((currentByte+1)*8-bitOffset-1));

						bitOffset++;
						if ((bitOffset != 0) && (bitOffset % 8) == 0)
							currentByte++;

						mask = mask >> 1;
					}
				}
			}
			// EndShapeRecord type
			else
			{
				// ShapeFlags bit-field
				numBits += 6;

				// Allocate memory
				if ((allocBytes*8 - bitOffset) < 6)
				{
					int oldAllocBytes = allocBytes;
					allocBytes++;
					if (pShapeRecordBuffer == NULL)
					{
						pShapeRecordBuffer = (UCHAR*)malloc(allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
					}
					else
					{
						UCHAR* pTempBuffer = (UCHAR*)malloc(oldAllocBytes*sizeof(UCHAR));
						memcpy(pTempBuffer, pShapeRecordBuffer, oldAllocBytes);
						pShapeRecordBuffer = (UCHAR*)realloc(pShapeRecordBuffer, allocBytes*sizeof(UCHAR));
						memset(pShapeRecordBuffer, 0, allocBytes);
						memcpy(pShapeRecordBuffer, pTempBuffer, oldAllocBytes);
						free(pTempBuffer);
					}
				}
			}
		}
	}

	// Set new RecordShapeArray length
	recordStreamLength = allocBytes;

	return pShapeRecordBuffer;
}

void CSWFShape::Scale(float scaleX, float scaleY)
{
	MATRIX_F matrix;
	m_TransformationMatrix.GetMatrix(matrix);

	matrix.scaleX = scaleX;
	matrix.scaleY = scaleY;

	m_TransformationMatrix.SetMatrix(matrix);
}

void CSWFShape::Rotate(float angle)
{
	MATRIX_F matrix;
	m_TransformationMatrix.GetMatrix(matrix);

	if (((int)angle % 90) == 0)
		angle += 0.05f;

	double a = PI / 180;
	matrix.scaleX = (float)cos(angle*a);
	matrix.scaleY = (float)cos(angle*a);
	matrix.rotateSkew0 = (float)sin(angle*a);
	matrix.rotateSkew1 = -(float)sin(angle*a);

	m_TransformationMatrix.SetMatrix(matrix);
}

void CSWFShape::Translate(float translateX, float translateY)
{
	MATRIX_F matrix;
	m_TransformationMatrix.GetMatrix(matrix);

	matrix.translateX = translateX;
	matrix.translateY = translateY;

	m_TransformationMatrix.SetMatrix(matrix);
}

void CSWFShape::Shear(float shearX, float shearY)
{
	MATRIX_F matrix;
	m_TransformationMatrix.GetMatrix(matrix);

	matrix.rotateSkew0 = shearX;
	matrix.rotateSkew1 = shearY;

	m_TransformationMatrix.SetMatrix(matrix);
}